<?php


namespace WenRuns\Laravel\Admin\Grid;


use Encore\Admin\Grid\Model;
use WenRuns\Laravel\Admin\Grid;
use WenRuns\Laravel\Admin\Grid\Column\CheckFilter;
use WenRuns\Laravel\Admin\Grid\Column\InputFilter;
use WenRuns\Laravel\Admin\Grid\Column\RangeFilter;
use WenRuns\Laravel\Admin\Grid\Column\Sorter;
use WenRuns\Laravel\Admin\Grid\Displayers\Image;


class Column extends \Encore\Admin\Grid\Column
{

    /**
     * @var null
     */
    protected $subColumn = null;

    /**
     * @var int
     */
    public $rowLevel = 0;

    /**
     * @var int
     */
    public $colspan = 1;

    /**
     * @return int
     */
    public function getColspan()
    {
        return $this->colspan - 1;
    }

    /**
     * @return SubColumn
     */
    public function getSubColumn()
    {
        if (empty($this->subColumn)) {
            $this->subColumn = new SubColumn($this);
        }
        return $this->subColumn;
    }


    /**
     * @return int
     */
    public function getRowspan()
    {
        $rowspan = 1;
        $row = count($this->getGrid()->mutators);
        if ($row > 0) {
            if (empty($this->subColumn)) {
                $rowspan = $row - $this->rowLevel + 1;
            }
        }
        return $rowspan;
    }

    /**
     * @return Grid
     */
    public function getGrid()
    {
        return $this->grid;
    }

    /**
     * @param \Closure $closure
     * @return $this
     */
    public function sub(\Closure $closure)
    {
        call_user_func($closure, $this->getSubColumn());
        $this->getGrid()->mutatorNames[] = $this->getName();
        return $this;
    }

    /**
     * @return string
     */
    public function formatHtmlAttributes()
    {
        $attrArr = [];
        foreach (static::getAttributes($this->name) as $name => $val) {
            $attrArr[] = "$name=\"$val\"";
        }

        return implode(' ', $attrArr);
    }

    /**
     * display回调函数
     * @param $value
     * @param $key
     * @return mixed
     */
    public function callDisplayCallbacks($value, $key)
    {
        return parent::callDisplayCallbacks($value, $key); // TODO: Change the autogenerated stub
    }

    /**
     * @param null $builder
     * @param null $formal
     * @param null $queryClosure
     *
     * @return $this|Column
     */
    public function filter($builder = null)
    {
        return $this->addFilter(...func_get_args());
    }

    /**
     * @param null $type
     * @param null $formal
     * @param null $queryClosure
     * @return $this|Column
     */
    protected function addFilter($type = null, $formal = null, $queryClosure = null)
    {
        if (is_array($type)) {
            return $this->addHeader(new CheckFilter($type, $queryClosure));
        }

        if (is_null($type)) {
            $type = 'equal';
        }

        if (in_array($type, ['equal', 'like', 'date', 'time', 'datetime'])) {
            return $this->addHeader(new InputFilter($type, $queryClosure));
        }

        if ($type === 'range') {
            if (is_null($formal)) {
                $formal = 'equal';
            }

            return $this->addHeader(new RangeFilter($formal, $queryClosure));
        }

        return $this;
    }

    public function bindFilterQuery(Model $model)
    {
        if ($this->filter) {
            $this->filter->addBinding(request($this->getName()), $model);
        }
    }

    /**
     * Add a column sortable to column header.
     *
     * @param string $cast
     *
     * @return Column|string
     */
    protected function addSorter($cast = null, \Closure $callback = null)
    {
        $sortName = $this->grid->model()->getSortName();

        $cloumnName = $this->getName();

        $sorter = new Sorter($sortName, $cloumnName, $cast, $callback);

        $this->getGrid()->sorters[$cloumnName] = $sorter;

        return $this->addHeader($sorter);
    }


    /**
     * Mark this column as sortable.
     *
     * @param null|string $cast
     *
     * @return Column|string
     */
    public function sortable($cast = null, \Closure $closure = null)
    {
        return $this->addSorter($cast, $closure);
    }



}
